/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ep.m005.ui.views;

import com.vaadin.data.Buffered.SourceException;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.data.Validator.InvalidValueException;
import com.vaadin.data.util.BeanItem;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.Field;
import com.vaadin.ui.Form;
import com.vaadin.ui.FormFieldFactory;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Panel;
import com.vaadin.ui.Table;
import com.vaadin.ui.TableFieldFactory;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.TextField;
import com.vaadin.ui.Window;
import com.vaadin.ui.Window.Notification;
import ep.libs.components.EditableTable;
import ep.libs.implementations.AbstractModule;
import ep.libs.implementations.AbstractView;
import ep.m001.ui.views.LoginView;
import ep.m002.module.M002Module;
import ep.m005.ui.controllers.M005Controller;
import ep.persistence.entities.T008Dosage;

/**
 *
 * @author skyr
 */
public class M005View extends AbstractView {
// <editor-fold defaultstate="collapsed" desc="captions">

    public static final String CAPTION_AMKA = "ΑΜΚΑ";
    public static final String CAPTION_SUBMIT = "Υποβολή";
    public static final String CAPTION_CANCEL = "Άκυρο";
    public static final String CAPTION_BACK = "Επιστροφή";
    public static final String CAPTION_DOCTOR = "Στοιχεία Ιατρού";
    public static final String CAPTION_PATIENT = "Στοιχεία Ασφαλισμένου";
    public static final String CAPTION_DIAGNOSIS = "Διάγνωση";
    public static final String CAPTION_DOSAGE = "Θεραπεία";
    public static final String CAPTION_PRESC = "Στοιχεία Συνταγής";
    public static final String CAPTION_FIRST_NAME = "'Ονομα";
    public static final String CAPTION_SURNAME = "Επώνυμο";
    public static final String CAPTION_ADDRESS = "Διευθυνση";
    public static final String CAPTION_CITY = "Πόλη";
    public static final String CAPTION_TK = "ΤΚ";
    public static final String CAPTION_YEAR_OF_BIRTH = "Ημ/νια Γέννησης.";
    public static final String CAPTION_PHONE = "Τηλέφωνο";
    public static final String CAPTION_INSURANCE = "Ταμείο Ασφάλισης";
    public static final String CAPTION_FATHER_NAME = "Πατρώνυμο";
    public static final String CAPTION_AMETAA = "Α.Μ.Ε.Τ.Α.Α";
    public static final String CAPTION_MOB = "Κινητό";
    public static final String CAPTION_EMAIL = "Email";
    public static final String CAPTION_SPECIALTY = "Ειδικότητα";
    public static final String CAPTION_CHRONIC = "Χρόνια Πάθηση";
    public static final String CAPTION_PRESC_DATE = "Ημ/νια Έκδοσης";
    public static final String CAPTION_BEGIN_DATE = "Ημ/νια Έναρξης Συνταγής";
    public static final String CAPTION_END_DATE = "Ημ/νια Λήξης Συνταγής";
    public static final String CAPTION_DIAGNOSIS_COMMENTS = "Σχόλια";
    public static final String CAPTION_MEDICINE = "Περιγραφή Φαρμάκου";
    public static final String CAPTION_QUANTITY = "Ποσότητα";
    public static final String CAPTION_WAY_OF_INPUT = "Οδός χορήγησης";
    public static final String CAPTION_FREQUENCY = "Συχνότητα";
    public static final String CAPTION_DURATION = "Διαρκεια";
    public static final String CAPTION_PRESCRIBED = "Παραδόθηκε";
    public static final String INFO_REQUIRED_TABLE_FIELDS = "Όλα τα πεδία του πίνακα είναι υποχρεωτικά.";
    public static final String INFO_REQUIRED = "Υποχρεωτικό πεδίο";
    public static final String ERROR_SAVE_FAIL = "Η αποθήκευση απέτυχε. Ελέγξτε τα πεδία για τυχόν λάθη.";
    public static final String SAVE_OK1 = "Η συνταγή του/της ";
    public static final String SAVE_OK2 = " αποθηκεύτηκε με επιτυχία.";
    public static final String ERROR_SUBSTANCE = "Έχετε επιλέξει φάρμακο με δραστική ουσία που δεν επιτρέπεται για το συγκεκριμένο ασθενή. Ουσία: ";
    public static final String ERROR_EMPTY = "Δεν έχετε εισάγει φάρμακα.";
    // </editor-fold>
    private M005Controller controller;
    protected Object patientObject;
    private Integer prescriptionId;
    // private GridLayout viewLayout;
    private Form patientForm;
    private Form doctorForm;
    protected Form prescForm;
    protected EditableTable dosageEditableTable;
    protected Button backButton;
    protected Button submitButton;
    private String[] patientStrings;
    private String[] doctorStrings;
    private String[] prescStrings;
    protected String[] dosageStrings;
    protected String[] dosageHeaders;
    protected HorizontalLayout buttonsLayout;
    protected TableFieldFactory tableFieldFactory;
    private ComboBox medicineCb;

    public M005View(AbstractModule module) {
        super(module);
    }

    public M005View(AbstractModule module, Object[] args) {
        super(module, args);
        this.patientObject = args[0];
        this.prescriptionId = (Integer) ((args.length == 2) ? args[1] : (-1));
    }

    @Override
    public ComponentContainer getView() {
        controller = new M005Controller(patientObject, prescriptionId, module);
        initializeFormStrings();
        initilizeComponents();
        initializeListeners();
        return viewLayout;
    }

    protected void initilizeComponents() {
        buttonsLayout = new HorizontalLayout();
        buttonsLayout.setSpacing(true);
        backButton = new Button(CAPTION_BACK);
        submitButton = new Button(CAPTION_SUBMIT);

        //read only patient form
        Panel patientPanel = new Panel(CAPTION_PATIENT);
        initializePatientForm();
        patientPanel.addComponent(patientForm);
        //read only doctor form
        Panel doctorPanel = new Panel(CAPTION_DOCTOR);
        initializeDoctorForm();
        doctorPanel.addComponent(doctorForm);
        //prescription
        Panel prescPanel = new Panel(CAPTION_PRESC);
        initializePrescForm();
        prescPanel.addComponent(prescForm);
        //medicines
        Panel dosagePanel = new Panel(CAPTION_DOSAGE);
        initializeDosageTable();
        dosagePanel.addComponent(dosageEditableTable);

        viewLayout.addComponent(doctorPanel);
        viewLayout.addComponent(patientPanel);
        viewLayout.addComponent(prescPanel);
        viewLayout.addComponent(dosagePanel);
        buttonsLayout.addComponent(backButton);
        buttonsLayout.addComponent(submitButton);
        viewLayout.addComponent(buttonsLayout);
    }

    protected void initializeListeners() {
        backButton.addListener(new Button.ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                changeModule();
            }
        });
        submitButton.addListener(new Button.ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                try {
                    prescForm.commit();
                    dosageEditableTable.getTable().commit();
                    boolean saveOk = save();
                    if (saveOk) {
                        changeModule();
                    }
                } catch (InvalidValueException invalidValueException) {
                }
            }
        });
    }

    protected void changeModule() {
        module.getApplication().changeModule(M002Module.class, new Object[]{LoginView.DOCTOR_TYPE, patientObject});
    }

    private void initializePatientForm() {
        patientForm = new Form(new GridLayout(5, 2));
        final FormFieldFactory oldFormFieldFactory = patientForm.getFormFieldFactory();
        patientForm.setFormFieldFactory(new FormFieldFactory() {

            @Override
            public Field createField(Item item, Object propertyId, Component uiContext) {
                Field f = oldFormFieldFactory.createField(item, propertyId, uiContext);
                if (propertyId.equals("firstName")) {
                    f.setCaption(CAPTION_FIRST_NAME);
                } else if (propertyId.equals("surname")) {
                    f.setCaption(CAPTION_SURNAME);
                } else if (propertyId.equals("amka")) {
                    f.setCaption(CAPTION_AMKA);
                } else if (propertyId.equals("yearOfBirth")) {
                    f.setCaption(CAPTION_YEAR_OF_BIRTH);
                } else if (propertyId.equals("address")) {
                    f.setCaption(CAPTION_ADDRESS);
                } else if (propertyId.equals("city")) {
                    f.setCaption(CAPTION_CITY);
                } else if (propertyId.equals("tk")) {
                    f.setCaption(CAPTION_TK);
                } else if (propertyId.equals("phone")) {
                    f.setCaption(CAPTION_PHONE);
                } else if (propertyId.equals("t004Insurance")) {
                    f.setCaption(CAPTION_INSURANCE);
                }
                if (f instanceof TextField) {
                    ((TextField) f).setNullRepresentation("");
                }
                f.setRequired(true);
                f.setRequiredError(f.getCaption());
                return f;
            }
        });
        patientForm.setItemDataSource(controller.getPatientDataSource());
        patientForm.setVisibleItemProperties(patientStrings);

        patientForm.setReadOnly(true);
    }

    private void initializeDoctorForm() {
        doctorForm = new Form(new GridLayout(5, 2));
        final FormFieldFactory oldFormFieldFactory = doctorForm.getFormFieldFactory();
        doctorForm.setFormFieldFactory(new FormFieldFactory() {

            @Override
            public Field createField(Item item, Object propertyId, Component uiContext) {
                Field f = oldFormFieldFactory.createField(item, propertyId, uiContext);
                if (propertyId.equals("firstName")) {
                    f.setCaption(CAPTION_FIRST_NAME);
                } else if (propertyId.equals("surname")) {
                    f.setCaption(CAPTION_SURNAME);
                } else if (propertyId.equals("amka")) {
                    f.setCaption(CAPTION_AMKA);
                } else if (propertyId.equals("fatherName")) {
                    f.setCaption(CAPTION_FATHER_NAME);
                } else if (propertyId.equals("specialty")) {
                    f.setCaption(CAPTION_SPECIALTY);
                } else if (propertyId.equals("ametaa")) {
                    f.setCaption(CAPTION_AMETAA);
                } else if (propertyId.equals("mob")) {
                    f.setCaption(CAPTION_MOB);
                } else if (propertyId.equals("phone")) {
                    f.setCaption(CAPTION_PHONE);
                } else if (propertyId.equals("email")) {
                    f.setCaption(CAPTION_EMAIL);
                }
                if (f instanceof TextField) {
                    ((TextField) f).setNullRepresentation("");
                }
                f.setRequired(true);
                f.setRequiredError(f.getCaption());
                return f;
            }
        });
        doctorForm.setItemDataSource(controller.getDoctorDataSource());
        doctorForm.setVisibleItemProperties(doctorStrings);
        doctorForm.setReadOnly(true);
    }

    private void initializePrescForm() {
        final GridLayout prescGridLayout = new GridLayout(4, 2) {

            @Override
            public void addComponent(Component component) {
                super.addComponent(component);
                this.setComponentAlignment(component, Alignment.BOTTOM_LEFT);
            }
        };
        prescGridLayout.setSpacing(true);
        prescForm = new Form(prescGridLayout) {

            @Override
            protected void attachField(Object propertyId, Field field) {
                if (propertyId.equals("diagnosisComments")) {
                    prescGridLayout.addComponent(field, 0, 1, 2, 1);
                } else {
                    super.attachField(propertyId, field);
                }
            }
        };
        final FormFieldFactory oldFormFieldFactory = prescForm.getFormFieldFactory();
        prescForm.setFormFieldFactory(new FormFieldFactory() {

            @Override
            public Field createField(Item item, Object propertyId, Component uiContext) {
                Field f = oldFormFieldFactory.createField(item, propertyId, uiContext);
                if (propertyId.equals("prescDate")) {
                    f.setCaption(CAPTION_PRESC_DATE);
                } else if (propertyId.equals("chronic")) {
                    f.setCaption(CAPTION_CHRONIC);
                } else if (propertyId.equals("beginDate")) {
                    f.setCaption(CAPTION_BEGIN_DATE);
                } else if (propertyId.equals("endDate")) {
                    f.setCaption(CAPTION_END_DATE);
                } else if (propertyId.equals("diagnosisComments")) {
                    TextArea textArea = new TextArea(CAPTION_DIAGNOSIS_COMMENTS);
                    textArea.setWidth("470px");
                    textArea.setNullRepresentation("");
                    f = textArea;
                } else if (propertyId.equals("t012Diagnosis")) {
                    ComboBox cb = new ComboBox(CAPTION_DIAGNOSIS);
                    cb.setContainerDataSource(controller.getDiagnosisDataSource());
                    cb.setWidth("280px");
                    f = cb;
                }
                if (f instanceof TextField) {
                    ((TextField) f).setNullRepresentation("");
                }
                f.setRequired(true);
                f.setRequiredError(f.getCaption());
                return f;
            }
        });
        prescForm.setItemDataSource(controller.getPrescDataSource());
        prescForm.setVisibleItemProperties(prescStrings);
    }

//    private void initializeDiagnosisForm() {
//        diagnosisForm = new Form();
//    }
    private void initializeDosageTable() {
        Label reqTableFields = new Label(INFO_REQUIRED_TABLE_FIELDS);
        reqTableFields.addStyleName("v-form-errormessage");

        tableFieldFactory = initializeTableFieldFactory();

        dosageEditableTable = new EditableTable(
                dosageStrings,
                dosageHeaders,
                controller.getDosageDataSource(),
                T008Dosage.class,
                tableFieldFactory,
                null);
        dosageEditableTable.getTable().setWidth("740px");
        dosageEditableTable.addComponent(reqTableFields);
        dosageEditableTable.getAddButton().addListener(new Button.ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                initializeMedicineWindow();
            }
        });
    }

    protected TableFieldFactory initializeTableFieldFactory() {
        final Table temp = new Table();
        TableFieldFactory tff = new TableFieldFactory() {

            @Override
            public Field createField(Container container, Object itemId, Object propertyId, Component uiContext) {
                Field f = temp.getTableFieldFactory().createField(container, itemId, propertyId, uiContext);
                if (propertyId.equals("t009Medicine")) {
                    medicineCb = new ComboBox();
                    medicineCb.setContainerDataSource(controller.getMedicineDataSource());
                    f = medicineCb;
                } else if (propertyId.equals("t013Frequency")) {
                    ComboBox cb = new ComboBox();
                    cb.setContainerDataSource(controller.getFrequencyDataSource());
                    f = cb;
                }
                if (f instanceof TextField) {
                    ((TextField) f).setNullRepresentation("");
                }
                f.setRequired(true);
                f.setRequiredError(INFO_REQUIRED);
                return f;
            }
        };
        return tff;
    }

    protected boolean save() {
        return save(false);
    }

    protected boolean save(boolean repeat) {
        if (dosageEditableTable.getTable().getItemIds().isEmpty()) {
            module.getApplication().getMainWindow().showNotification(ERROR_EMPTY, Notification.TYPE_ERROR_MESSAGE);
        } else {
            String illegalSubstance = controller.checkSubstances(dosageEditableTable.getTable().getItemIds());
            if (illegalSubstance == null) {

                Boolean saveok = false;
                saveok = controller.save((BeanItem) prescForm.getItemDataSource(), dosageEditableTable.getTable().getItemIds(), repeat);
                if (saveok) {
                    module.getApplication().getMainWindow().showNotification(SAVE_OK1 + patientObject.toString() + SAVE_OK2, Notification.TYPE_TRAY_NOTIFICATION);
                    return true;
                } else {
                    module.getApplication().getMainWindow().showNotification(ERROR_SAVE_FAIL, Notification.TYPE_ERROR_MESSAGE);
                }
            } else {
                module.getApplication().getMainWindow().showNotification(ERROR_SUBSTANCE + illegalSubstance, Notification.TYPE_ERROR_MESSAGE);
            }
        }
        return false;

    }

    private void initializeMedicineWindow() {
        SelectMedicineView medicineView = new SelectMedicineView(module, null, medicineCb);
        Window w = new Window();
        w.setWidth("800px");
        w.setModal(true);
        w.center();
        w.addComponent(medicineView.getView());
        module.getApplication().getMainWindow().addWindow(w);
    }

    protected void initializeFormStrings() {
        patientStrings = new String[]{
                    "firstName",
                    "surname",
                    "amka",
                    "yearOfBirth",
                    "address",
                    "city",
                    "tk",
                    "phone",
                    "t004Insurance"
                };
        doctorStrings = new String[]{
                    "firstName",
                    "surname",
                    "fatherName",
                    "specialty",
                    "amka",
                    "ametaa",
                    "phone",
                    "mob",
                    "email"
                };

        prescStrings = new String[]{
                    //                    "prescDate",
                    "beginDate",
                    "endDate",
                    "chronic",
                    "t012Diagnosis",
                    "diagnosisComments"
                };
        dosageStrings = new String[]{
                    "t009Medicine",
                    "quantity",
                    "wayOfInput",
                    "t013Frequency",
                    "duration"
                //                    "prescribed"
                };

        dosageHeaders = new String[]{
                    CAPTION_MEDICINE,
                    CAPTION_QUANTITY,
                    CAPTION_WAY_OF_INPUT,
                    CAPTION_FREQUENCY,
                    CAPTION_DURATION //                    CAPTION_PRESCRIBED
                };
    }
}
